package com.nengchuan.eic.nceconomy.component.excel;

import com.nengchuan.eic.nceconomy.constant.CategoryEnum;
import com.nengchuan.eic.nceconomy.constant.CommonConstant;
import com.nengchuan.eic.nceconomy.constant.IndexDictErrorEnum;
import com.nengchuan.eic.nceconomy.entity.po.ExcelSheet;
import com.nengchuan.eic.nceconomy.entity.po.OriginIndexData;
import com.nengchuan.eic.nceconomy.entity.po.VerifyResult;
import com.nengchuan.eic.nceconomy.entity.vo.IndexDictCodeVO;
import com.nengchuan.eic.nceconomy.service.IndexDictService;
import com.nengchuan.eic.nceconomy.util.ExcelSerialNumUtils;
import com.nengchuan.eic.nceconomy.util.IdSequence;
import com.nengchuan.util.NullCheckUtils;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 处理辅助类
 */
@Component("excelHandlerSupport")
public class HandlerSupport {

    @Autowired
    private  IndexDictService indexDictService;

    //需要检查为空的sheet集合
    private final static String[] CHECK_EMPTY_SHEET_NAME={"表一","表二"};

    //需要将空序号存为子序号的sheet集合
    private final static String[] EMPTY_SERIAL_NUM_SON_SHEET_NAME={"建筑单位工程汇总表","安装单位工程汇总表","架空输电线路工程单位工程汇总表","辅助费用表","主要设备材料汇总表","建筑安装工程施工费用结算一览表","安装工程施工费用结算一览表"};
    private static List<String> nameList= Arrays.asList("【甲供设备】","【甲供材料】");
    private static List<String> parentList= Arrays.asList("建筑工程","安装工程");

    /**
     * 对excel数据进行强制校验
     * 1.必需的sheetName必须存在
     * 2.值的第一行第一列必须得有值
     *
     * @param data 用户数据
     * @param prefixs sheetName前缀
     * @param suffixs   sheetName后缀
     * @param suffixs   fieldIdxEnd 确定数据所在行
     * @param suffixs   dataIdxStart 确定数据所在列
     * @return 校验结果,没有问题则为空
     */
    public List<VerifyResult> forceVerify(Map<String,List<String[]>> data,
                               String[] prefixs,
                               String[] suffixs,
                               int[] fieldIdxEnd,
                               int[] dataIdxStart){
        List<VerifyResult> verifyResults=new ArrayList<>();
        VerifyResult verifyResult;
        boolean fullMatch;
        boolean likeMatch;
        String templateSheetName;
        int errorType;
        String errorMsg;
        int status;
        String sheetName;
        List<String[]> metadata;

        for (int i = 0; i < prefixs.length; i++) {
            fullMatch=false;
            likeMatch=false;
            sheetName=null;
            metadata=null;
            if(suffixs.length!=0){
                templateSheetName=prefixs[i]+"（"+suffixs[i]+"）";
            }else {
                templateSheetName=prefixs[i];
            }
            if(templateSheetName.contains("表三戊")){
                continue;
            }
            //遍历用户上传的数据,key为sheetName,value为sheet内容
            for (Map.Entry<String, List<String[]>> e : data.entrySet()) {
                sheetName = e.getKey();
                metadata = e.getValue();
                //如果sheetName存在,则将相应的标志位置为true
                if(templateSheetName.equals(sheetName)){
                    fullMatch=true;
                    break;
                }else if (sheetName.contains(prefixs[i])) {
                    likeMatch=true;
                    break;
                }
            }

            if(fullMatch){
                errorType= IndexDictErrorEnum.SHEET_NAME_FULL_MATCH.type;
                errorMsg=String.format("sheet名匹配,sheet名:[%s]", sheetName);
                status=CommonConstant.verifyResult.STATUS_PASS;
            }else if(likeMatch){
                errorType= IndexDictErrorEnum.SHEET_NAME_LIKE_MATCH.type;
                errorMsg=String.format("sheet名模糊匹配,sheet名:[%s],模板sheet名:[%s]", sheetName,templateSheetName);
                status=CommonConstant.verifyResult.STATUS_WARN;
            }else{
                errorType= IndexDictErrorEnum.MISS_SHEET.type;
                errorMsg=String.format("sheet名不匹配,sheet名:[%s]", sheetName);
                status=CommonConstant.verifyResult.STATUS_FAIL;
                sheetName=null;
            }

            verifyResult=VerifyResult
                    .builder()
                    .checkType(CommonConstant.verifyResult.CHECK_TYPE_SHEET)
                    .templateSheetName(templateSheetName)
                    .sheetName(sheetName)
                    .errorType(errorType)
                    .errorMsg(errorMsg)
                    .status(status)
                    .build();
            verifyResults.add(verifyResult);

            if((fullMatch||likeMatch)&&isCheckEmptySheet(templateSheetName)){
                String val = metadata.get(fieldIdxEnd[i] + 1)[dataIdxStart[i]];
                status=CommonConstant.verifyResult.STATUS_FAIL;
                if (NullCheckUtils.isNull(val)) {
                    errorMsg=String.format("sheet为空,sheet名:[%s]",sheetName);
                    verifyResult=VerifyResult
                            .builder()
                            .checkType(CommonConstant.verifyResult.CHECK_TYPE_SHEET)
                            .errorType(IndexDictErrorEnum.EMPTY_SHEET.type)
                            .sheetName(sheetName)
                            .templateSheetName(templateSheetName)
                            .errorMsg(errorMsg)
                            .lineNum(fieldIdxEnd[i] + 1)
                            .rowNum(dataIdxStart[i])
                            .status(status)
                            .build();
                    verifyResults.add(verifyResult);
                }
            }
        }

        return verifyResults;
    }

    /**
     * 创建excel数据对象
     * @param metaData  解析的原始数据
     * @param response  封装的响应对象
     * @param requestModel 请求model
     * @param fieldIdxEnd 字段结束下标
     * @param lineIndxIdx 行指标下标
     * @param dataIdxStart 数据起始下标
     * @param verifyResults 验证结果集合
     */
    public  void createExcelDic(List<String[]> metaData,
                                      ExcelModel response,
                                      RequestModel requestModel,
                                      int fieldIdxEnd,
                                      int lineIndxIdx,
                                      int dataIdxStart,
                                      List<VerifyResult> verifyResults) {
        //读取标题抬头等信息
        List<OriginIndexData> originIndexDatas=setTitle(metaData);

        //读取所有的行指标,如果有多行合并成一行 以"-"为分隔符
        Map<Integer,RowIndexModel> indexMap=setFieldAndGetIndexMap(originIndexDatas,metaData,fieldIdxEnd,requestModel,verifyResults);

        //存储所有数据
        setData(originIndexDatas,metaData,indexMap,requestModel,verifyResults,fieldIdxEnd+1,lineIndxIdx,dataIdxStart);

        response.setOriginIndexData(originIndexDatas);
    }

    /**
     * 创建excelsheet对象
     * @param templateSheetId 模板sheetId
     * @param sheetName sheet名
     * @param order 排序字段记录
     * @return
     */
    public  ExcelSheet createExcelSheet(Long templateSheetId,String sheetName,int order) {
        return ExcelSheet.builder().userSheetName(sheetName).templateSheetId(templateSheetId).sequence(order).delFlag(0).build();
    }

    /**
     * 设置数据
     * @param originIndexDatas 存储PO对象的容器
     * @param metaData 解析的原始对象集合
     * @param rowIndexMap 指标映射集合
     * @param verifyResults 校验结果
     * @param fieldIdxEnd 字段的结束下标,也就是非模板数据的起始坐标
     * @param lineIndxIdx 行指标地址
     * @param dataStartIdx 用户填写数据
     */
    private  void setData(List<OriginIndexData> originIndexDatas,
                                List<String[]> metaData,
                                Map<Integer,RowIndexModel> rowIndexMap,
                                RequestModel requestModel,
                                List<VerifyResult> verifyResults,
                                int fieldIdxEnd,
                                int lineIndxIdx,
                                int dataStartIdx) {

        //获取数据的起始下标
        if(fieldIdxEnd>=metaData.size()){
            return;
        }

        //将所有行指标查询出来
//        List<String> lineIndexNames=new ArrayList<>(metaData.size()-fieldIdxEnd);
//        for (int i = fieldIdxEnd; i <metaData.size() ; i++) {
//            String[] datas=metaData.get(i);
//            if(lineIndxIdx<datas.length){
//                lineIndexNames.add(datas[lineIndxIdx]);
//            }
//        }
//        Map<String,String> lineIndexMap=new HashMap<>(lineIndexNames.size()/3*4+1);
//        List<IndexDict> indexDicts=indexDictService.findByNames(lineIndexNames);
//        indexDicts.forEach(e->lineIndexMap.put(e.getName(),e.getCode()));


        //创建历史序号对象
        List<OriginIndexData> historySerialNum=new ArrayList<>(metaData.size()-fieldIdxEnd);
        int order= getNewestOrder(originIndexDatas);

        String lineIndex;
        IndexDictCodeVO indexDictCodeVO;
        VerifyResult verifyResult;
        String tempalteSerialNum;
        String templateVal;
        boolean lineIsMatch;

        OriginIndexData serialNumOriginIndexData;
        for (int i = fieldIdxEnd; i <metaData.size() ; i++) {
            String[] datas=metaData.get(i);
            lineIndex=null;
            serialNumOriginIndexData=null;
            tempalteSerialNum=null;
            templateVal=null;
            lineIsMatch=true;
            for (int j = 0; j <datas.length ; j++) {
                String data=datas[j];
                //存储序号,并分辨序号上下级关系
                if(j==0){
                    if(requestModel.getSheetName().contains("主要设备材料汇总表")){
                        setSeq(originIndexDatas,historySerialNum,requestModel.getSheetName(), data,order, i,datas[j+1],rowIndexMap.get(j));
                    }else{
                        setSeq(originIndexDatas,historySerialNum,requestModel.getSheetName(), data,order, i,rowIndexMap.get(j));
                    }
                    order= getNewestOrder(originIndexDatas);
                    serialNumOriginIndexData=originIndexDatas.get(originIndexDatas.size()-1);
                    continue;
                }

                //如果数据到达指标点,指标不为空,序号不为空或者是表一,则将line指标查询出来
                if(j==lineIndxIdx&&
                        NullCheckUtils.isNotNull(datas[j])&&
                        (NullCheckUtils.isNotNull(serialNumOriginIndexData.getValue())||requestModel.getSheetName().contains("表一")||CategoryEnum.SETTLE.code.equals(requestModel.getCategoryCode()))){

                    //获取上级指标
                    String parentCode=null;
                    if(serialNumOriginIndexData.getParentId()!=null){
                        parentCode=getParentLineIndex(historySerialNum,serialNumOriginIndexData);
                    }

                    indexDictCodeVO=indexDictService.lookUpCode(serialNumOriginIndexData.getValue()==null?"":serialNumOriginIndexData.getValue().trim(),datas[j]==null?"":datas[j].trim(),requestModel.getSheetName(),parentCode,requestModel.getProjectCode(),requestModel.getCategoryCode());

                    if(NullCheckUtils.isNotNull(indexDictCodeVO.getIndexDict())){
                        tempalteSerialNum=indexDictCodeVO.getIndexDict().getSerialNum();
                        templateVal=indexDictCodeVO.getIndexDict().getName();
                    }

                    if(indexDictCodeVO.getErrorType()!=0){
                        verifyResult=VerifyResult
                                .builder()
                                .checkType(CommonConstant.verifyResult.CHECK_TYPE_CONTENT)
                                .sheetName(requestModel.getSheetName())
                                .errorType(indexDictCodeVO.getErrorType())
                                .errorMsg(indexDictCodeVO.getErrorMsg())
                                .templateSerialNum(tempalteSerialNum)
                                .templateVal(templateVal)
                                .excelSerialNum(serialNumOriginIndexData.getValue())
                                .excelVal(datas[j])
                                .lineNum(i)
                                .rowNum(j)
                                .status(CommonConstant.verifyResult.STATUS_WARN)
                                .build();
                        verifyResults.add(verifyResult);
                        lineIsMatch=false;
                    }

                    lineIndex=indexDictCodeVO.getLineCode();
                    if(historySerialNum.size()>0){
                        historySerialNum.get(historySerialNum.size()-1).setLineIndex(lineIndex);
                    }

                }

                OriginIndexData originIndexData=OriginIndexData
                        .builder()
                        .id(IdSequence.generateId())
                        .lineStartCoordinates(i)
                        .lineEndCoordinates(i)
                        .rowStartCoordinates(j)
                        .rowEndCoordinates(j)
                        .sequence(order++)
                        .value(data.trim())
                        .delFlag(0)
                        .build();
                originIndexDatas.add(originIndexData);

                //如果下标大于指标点,则将指标存储到数据中
//                if(j>=dataStartIdx){
                    //TODO 为用户存储行指标与列指标
                    RowIndexModel rowIndexModel=rowIndexMap.get(j);
                    originIndexData.setRowIndex(rowIndexModel.rowIndex); //TODO 存储指标状态
                    originIndexData.setLineIndex(lineIndex);
                    originIndexData.setTemplateFlag(String.valueOf(lineIsMatch&&rowIndexModel.isMatch));
                    if(NullCheckUtils.isNull(serialNumOriginIndexData.getTemplateFlag())){
                        serialNumOriginIndexData.setTemplateFlag(String.valueOf(lineIsMatch&&rowIndexModel.isMatch));
                    }
//                }
            }

        }
    }


    /**
     * 是否检车该sheet为空
     * @param sheetName
     * @return
     */
    private boolean isCheckEmptySheet(String sheetName){
        for (String s : CHECK_EMPTY_SHEET_NAME) {
            if(sheetName.contains(s)){
                return true;
            }
        }

        return false;
    }

    /**
     * 获取当前数据的上级行指标
     * @param originIndexDatas 数据集合
     * @param originIndexData 当前节点
     * @return
     */
    private String getParentLineIndex(List<OriginIndexData> originIndexDatas,OriginIndexData originIndexData){
        for (OriginIndexData indexData : originIndexDatas) {
            if(indexData.getId()==originIndexData.getParentId().longValue()){
                return indexData.getLineIndex();
                // 以下是寻找顶级节点的用户
//                if(indexData.getParentId()==null){
//                    return indexData.getLineIndex();
//                }else{
//                    return getParentLineIndex(originIndexDatas,indexData);
//                }
            }
        }
        return null;
    }

    /**
     * 获取集合中最新的排序字段
     * @param originIndexDatas
     * @return
     */
    private  Integer getNewestOrder(List<OriginIndexData> originIndexDatas) {
        return originIndexDatas.size()>0?originIndexDatas.get(originIndexDatas.size() - 1).getSequence()+1:0;
    }

    /**
     * 设置序号
     * @param originIndexDatas PO对象集合
     * @param order 排序字段
     * @param i 下标
     * @param seq 序号
     * @return
     */
    private  void setSeq(List<OriginIndexData> originIndexDatas,
                              List<OriginIndexData> history,
                              String sheetName,
                              String seq,
                              int order,
                              int i,RowIndexModel rowIndexModel) {

        OriginIndexData originIndexData=OriginIndexData
                .builder()
                .id(IdSequence.generateId())
                .lineStartCoordinates(i)
                .lineEndCoordinates(i)
                .rowStartCoordinates(0)
                .rowEndCoordinates(0)
                .sequence(order++)
                .rowIndex(rowIndexModel.rowIndex)
                .value(seq)
                .delFlag(0)
                .build();

        Long parentId;
        if(NullCheckUtils.isNull(seq)&&isEmptySerialNumBecomeSon(sheetName)){
            parentId=ExcelSerialNumUtils.getParentSequenceTable3(history,originIndexData);
        }else{
            parentId=ExcelSerialNumUtils.getParentSequence(history,originIndexData);
        }
        originIndexData.setParentId(parentId);
        originIndexDatas.add(originIndexData);
    }
    /**
     * 设置序号
     * @param originIndexDatas PO对象集合
     * @param order 排序字段
     * @param i 下标
     * @param seq 序号
     * @return
     */
    private  void setSeq(List<OriginIndexData> originIndexDatas,
                         List<OriginIndexData> history,
                         String sheetName,
                         String seq,
                         int order,
                         int i,String name,RowIndexModel rowIndexModel) {

        OriginIndexData originIndexData=OriginIndexData
                .builder()
                .id(IdSequence.generateId())
                .lineStartCoordinates(i)
                .lineEndCoordinates(i)
                .rowStartCoordinates(0)
                .rowEndCoordinates(0)
                .sequence(order++)
                .rowIndex(rowIndexModel.rowIndex)
                .value(seq)
                .delFlag(0)
                .build();

        if(nameList.contains(name)){
            originIndexDatas.add(originIndexData);
            return;
        }

        Long parentId=null;
        if(NullCheckUtils.isNull(seq)&&isEmptySerialNumBecomeSon(sheetName)){
            if(parentList.contains(name)){
                 history.add(originIndexData);
            }else{
                if(NullCheckUtils.isNull(seq)||ExcelSerialNumUtils.isDownSeq(seq)){
                    for (int j = history.size() - 2; j >= 0; j--) {
                        String tempSeq=history.get(j).getValue();
                        if(NullCheckUtils.isNotNull(tempSeq)){
                            parentId= history.get(j).getId();
                        }
                    }
                }
            }
        }else{
            parentId=ExcelSerialNumUtils.getParentSequence(history,originIndexData,sheetName);
        }
        originIndexData.setParentId(parentId);
        originIndexDatas.add(originIndexData);
    }
    /**
     * 是否将空序号存储为子序号(其他sheet空序号为顶级父序号)
     * @param sheetName
     * @return
     */
    private boolean isEmptySerialNumBecomeSon(String sheetName){
        for (String s : EMPTY_SERIAL_NUM_SON_SHEET_NAME) {
            if(sheetName.contains(s)){
                return true;
            }
        }
        return false;
    }

    /**
     * 获取标题、抬头等信息
     * @param metaData 解析的原始数据
     * @return
     */
    private  List<OriginIndexData> setTitle(List<String[]> metaData){
        int order=0;

        //获取标题与数据的分割下标
        int segmentIndex=getTitleAndDataSegmentIndex(metaData);

        List<OriginIndexData> originIndexDatas=new ArrayList<>();
        //如果分割下标小于1，则代表没有标题信息
        if(segmentIndex<1){
            return originIndexDatas;
        }

        for (int i = 0; i <segmentIndex ; i++) {
            String[] str=metaData.get(i);
            for (int j = 0; j < str.length; j++) {
                String val=str[j];
                OriginIndexData single;
                if(NullCheckUtils.isNull(val)){
                    //横向向前寻找第一个不为空的元素,并将自己的坐标设置到不为空元素的结束坐标上
                    single=getLastOriginIndexData(originIndexDatas);


                    //如果最后一个对象不为空,并且对象的行坐标包含当前坐标,则将当前坐标值设置到结尾坐标
                    if(single!=null&&
                            (single.getLineStartCoordinates()<=i&&single.getLineEndCoordinates()>=i)){
                        int newRowEnd=single.getRowEndCoordinates()<j?j:single.getRowEndCoordinates();
                        single.setRowEndCoordinates(newRowEnd);
                        continue;
                    }
                }else{
                    single=OriginIndexData
                            .builder()
                            .id(IdSequence.generateId())
                            .lineStartCoordinates(i)
                            .lineEndCoordinates(i)
                            .rowStartCoordinates(j)
                            .rowEndCoordinates(j)
                            .sequence(order++)
                            .value(val)
                            .delFlag(0)
                            .build();
                    originIndexDatas.add(single);
                }
            }
        }
        return originIndexDatas;
    }


    /**
     * 获取可用长度
     * @param metadata
     * @param startIdx
     * @param endIdx
     * @return
     */
    private int getUsableSize(List<String[]> metadata,int startIdx,int endIdx){
        int usableSize=Integer.MAX_VALUE;
        int tempSize;
        for (int i = startIdx; i <=endIdx; i++) {
            tempSize=metadata.get(i).length;
            if(tempSize<usableSize){
                usableSize=tempSize;
            }
        }
        return usableSize;
    }

    /**
     * 获取前驱不为空的节点
     * @param data
     * @param endIdx
     * @return
     */
    private String getPrecursorNode(String[] data,int endIdx){
        for (int i = endIdx - 1; i >= 0; i--) {
            if(NullCheckUtils.isNotNull(data[i])){
                return data[i];
            }
        }
        return "";
    }

    /**
     * 解析列指标
     * @param allData 所有解析后数据
     * @param metadata 原始数据
     * @param endIdx 列指标结束下标
     * @param requestModel 请求对象
     * @return 列指标key集合
     */
    private Map<Integer,RowIndexModel> setFieldAndGetIndexMap(List<OriginIndexData> allData,
                                                List<String[]> metadata,
                                                int endIdx,
                                                RequestModel requestModel,
                                                List<VerifyResult> verifyResults){
        //获取字段的起始下标
        int startIdx=getTitleAndDataSegmentIndex(metadata);

        if(startIdx<0||endIdx>=metadata.size()){
            return Collections.EMPTY_MAP;
        }
        int usableSize=getUsableSize(metadata,startIdx,endIdx);
        List<OriginIndexData> originIndexDatas=new ArrayList<>(usableSize);
        OriginIndexData originIndexData;
        String bucketData;
        boolean isEmpty;
        String tempData;
        for (int i = 0; i < usableSize; i++) {
            bucketData="";
            isEmpty=true;
            for (int j = endIdx; j >= startIdx; j--) {
                tempData=metadata.get(j)[i];
                if(!isEmpty){
                    if(NullCheckUtils.isNull(tempData)){
                        tempData=getPrecursorNode(metadata.get(j),i);
                    }
                }

                if(NullCheckUtils.isNotNull(tempData)){
                    isEmpty=false;
                    tempData=NullCheckUtils.isNull(bucketData)?tempData:tempData+"-"+bucketData;
                }
                bucketData=tempData;

            }
            if(NullCheckUtils.isNull(bucketData)&&originIndexDatas.size()>0){
                originIndexData=originIndexDatas.get(originIndexDatas.size()-1);
                originIndexData.setRowEndCoordinates(i);
            }else{
                String[] vals = splitUnit(bucketData);
                originIndexData = OriginIndexData
                        .builder()
                        .id(IdSequence.generateId())
                        .lineStartCoordinates(startIdx)
                        .lineEndCoordinates(endIdx)
                        .rowStartCoordinates(i)
                        .rowEndCoordinates(i)
                        .value(vals[0])
                        .unit(vals[1])
                        .delFlag(0)
                        .build();
            }
            originIndexDatas.add(originIndexData);

        }

        AtomicInteger order= new AtomicInteger(getNewestOrder(allData));
        originIndexDatas.forEach(e->e.setSequence(order.getAndIncrement()));
        allData.addAll(originIndexDatas);

        //获取所有数据,去数据库查询指标code与name的映射关系
        Map<Integer,RowIndexModel> indexMap=new HashMap<>(originIndexDatas.size()/3*4+1);
        OriginIndexData rowRriginIndexData;
        IndexDictCodeVO indexDictCodeVO;
        VerifyResult verifyResult;
        String templateVal;
        boolean isMatch;
        for (int i = 0; i < originIndexDatas.size(); i++) {
            templateVal=null;
            isMatch=true;
            rowRriginIndexData=originIndexDatas.get(i);
            indexDictCodeVO=indexDictService.lookUpRowCode(StringUtils.isNotBlank(rowRriginIndexData.getUnit())?concatValAndUnit(rowRriginIndexData.getValue(),rowRriginIndexData.getUnit()):rowRriginIndexData.getValue(),requestModel.getProjectCode(),requestModel.getCategoryCode());

            if(NullCheckUtils.isNotNull(indexDictCodeVO.getIndexDict())){
                templateVal=indexDictCodeVO.getIndexDict().getName();
            }

            if(indexDictCodeVO.getErrorType()!=0){
                verifyResult=VerifyResult
                        .builder()
                        .checkType(IndexDictErrorEnum.EMPTY_SHEET.type)
                        .sheetName(requestModel.getSheetName())
                        .errorType(indexDictCodeVO.getErrorType())
                        .errorMsg(indexDictCodeVO.getErrorMsg())
                        .templateVal(templateVal)
                        .excelVal(rowRriginIndexData.getValue())
                        .lineNum(rowRriginIndexData.getLineStartCoordinates())
                        .rowNum(rowRriginIndexData.getRowStartCoordinates())
                        .status(CommonConstant.verifyResult.STATUS_WARN)
                        .build();
                verifyResults.add(verifyResult);
                isMatch=false;
            }
            indexMap.put(rowRriginIndexData.getRowStartCoordinates(),new RowIndexModel(indexDictCodeVO.getLineCode(),isMatch));

        }

//        List<IndexDict> indexDicts=indexDictService.findByNames(indexKey);
//        for (IndexDict indexDict : indexDicts) {
//            for (int i = 0; i < originIndexDatas.size(); i++) {
//                originIndexData=originIndexDatas.get(i);
//                if(indexDict.getName().equals(originIndexData.getValue())){
//                    indexMap.put(originIndexData.getRowStartCoordinates(),indexDict.getCode());
//                }
//
//            }
//        }
        return indexMap;
    }


    /**
     *设置字段数据和获取指标映射
     * @param allData 所有PO对象集合
     * @param metadata 解析的元数据
     * @param endIdx 结束下标
     */
//    private  Map<String,String> setFieldAndGetIndexMap(List<OriginIndexData> allData,List<String[]> metadata,int endIdx){
//        //获取字段的起始下标
//        int startIdx=getTitleAndDataSegmentIndex(metadata);
//
//        if(startIdx<0||endIdx>=metadata.size()){
//            return Collections.EMPTY_MAP;
//        }
//
//
//        List<OriginIndexData> originIndexDatas=new ArrayList<>();
//
//        //两层循环遍历字段二维表
//        OriginIndexData originIndexData;
//        OriginIndexData tempOriginIndexData;
//        for (int i = startIdx; i <=endIdx; i++) {
//            String[] lineArr=metadata.get(i);
//            for (int j = 0; j < lineArr.length; j++) {
//
//                //获取包含当前行的对象,如果为空,则新建
//                int includeIdx=getIncludeCurrRowBean(originIndexDatas,j);
//                originIndexData=null;
//                if(includeIdx>=0){
//                    originIndexData=originIndexDatas.get(includeIdx);
//                }
//                String fieldVal=lineArr[j];
//
//                if(originIndexData==null) {
//                    //如果值为空,则获取上一个对象,并把当前坐标设置到最后
//                    if (NullCheckUtils.isNull(fieldVal)) {
//                        originIndexData = getLastOriginIndexData(originIndexDatas);
//
//                        //如果上一个对象不为空
//                        if (originIndexData != null) {
//                            //如果当前对象与最后一个对象在同一行,则将当前下标设置成上一个对象的列结束坐标
//                            if (originIndexData.getLineStartCoordinates() <= i && originIndexData.getLineEndCoordinates() >= i) {
//                                int newRowEnd = originIndexData.getRowEndCoordinates() < j ? j : originIndexData.getRowEndCoordinates();
//                                originIndexData.setRowEndCoordinates(newRowEnd);
//                            }
//                        }
//
//                    } else {
//                        String[] vals = splitUnit(fieldVal);
//                        originIndexData = OriginIndexData
//                                .builder()
//                                .id(IdSequence.getId())
//                                .lineStartCoordinates(i)
//                                .lineEndCoordinates(i)
//                                .rowStartCoordinates(j)
//                                .rowEndCoordinates(j)
//                                .value(vals[0])
//                                .unit(vals[1])
//                                .delFlag(0)
//                                .build();
//                        originIndexDatas.add(originIndexData);
//                    }
//
//                }else{
//                    if(NullCheckUtils.isNull(fieldVal)){
//                        //如果当前对象与最后一个对象在同一行,则将当前下标设置成上一个对象的列结束坐标
//                        //否则,获取与当前列一致的对象,并设置当前下标为该对象的行结束坐标
//                        if (originIndexData.getLineStartCoordinates() <= i && originIndexData.getLineEndCoordinates() >= i) {
//                            int newRowEnd = originIndexData.getRowEndCoordinates() < j ? j : originIndexData.getRowEndCoordinates();
//                            originIndexData.setRowEndCoordinates(newRowEnd);
//                        }else{
//                            int newLineEnd=originIndexData.getLineEndCoordinates()<i?i:originIndexData.getLineEndCoordinates();
//                            originIndexData.setLineEndCoordinates(newLineEnd);
//                            originIndexData.setRowEndCoordinates(j);
//                        }
//                    }else{
//                        String[] vals = splitUnit(fieldVal);
//                        String newVal;
//                         if(originIndexData.getLineStartCoordinates()<=i&&originIndexData.getLineEndCoordinates()>=i){
//                            int lastIndex=originIndexData.getValue().lastIndexOf("-");
//                            String valPrefix=null;
//                            if(lastIndex>=0){
//                                valPrefix=originIndexData.getValue().substring(0,lastIndex)+"-";
//                                newVal=valPrefix+vals[0];
//                            }else{
//                                newVal=vals[0];
//                            }
//                            tempOriginIndexData = OriginIndexData
//                                    .builder()
//                                    .id(IdSequence.getId())
//                                    .lineStartCoordinates(originIndexData.getLineStartCoordinates())
//                                    .lineEndCoordinates(i)
//                                    .rowStartCoordinates(originIndexData.getRowStartCoordinates())
//                                    .rowEndCoordinates(originIndexData.getRowEndCoordinates())
//                                    .value(newVal)
//                                    .unit(vals[1])
//                                    .delFlag(0)
//                                    .build();
//                            if(NullCheckUtils.isNull(valPrefix)){
//                                originIndexDatas.add(includeIdx+1,tempOriginIndexData);
//                            }else{
//                                originIndexDatas.add(getLastIncludePrefixIndex(originIndexDatas,valPrefix)+1,tempOriginIndexData);
//                            }
//                        }else{
//                            newVal=originIndexData.getValue()+"-"+vals[0];
//                            originIndexData.setValue(newVal);
//                            originIndexData.setUnit(vals[1]);
//                            originIndexData.setLineEndCoordinates(i);
//                        }
//                    }
//                }
//            }
//        }
//        AtomicInteger order= new AtomicInteger(getNewestOrder(allData));
//        originIndexDatas.forEach(e->e.setSequence(order.getAndIncrement()));
//        allData.addAll(originIndexDatas);
//
//        //获取所有数据,去数据库查询指标code与name的映射关系
//        List<String> indexKey=originIndexDatas.stream().map(e->e.getValue()).collect(Collectors.toList());
//        List<IndexDict> indexDicts=indexDictService.findByNames(indexKey);
//        Map<String,String> indexMap=new HashMap<>(indexDicts.size()/3*4+1);
//        indexDicts.forEach(e->indexMap.put(e.getName(),e.getCode()));
//        return indexMap;
//    }

    /**
     * 获取具有相同前缀val的元素下标
     * @param originIndexData
     * @param prefix
     * @return
     */
    private int getLastIncludePrefixIndex(List<OriginIndexData> originIndexData,String prefix){
        String value;
        for (int i = originIndexData.size() - 1; i >= 0; i--) {
            value=originIndexData.get(i).getValue();
            if(NullCheckUtils.isNotNull(value)&&value.contains(prefix)){
                return i;
            }
        }
        return originIndexData.size();
    }

    /**
     * 获取包含当前列的对象下标
     * @param params
     * @param idx
     * @return
     */
    private  int getIncludeCurrRowBean(List<OriginIndexData> params,int idx){
        for (int i = 0; i < params.size(); i++) {
            OriginIndexData originIndexData=params.get(i);
            if(originIndexData.getRowStartCoordinates()<=idx&&originIndexData.getRowEndCoordinates()>=idx){
                return i;
            }
        }
        return -1;
    }


    /**
     * 获取标题与实际数据的分割下标
     * @param params
     * @return
     */
    private  int getTitleAndDataSegmentIndex(List<String[]> params){
        for (int i = 0; i < params.size(); i++) {
            String[] strs=params.get(i);
            if(strs.length>0&&"序号".equals(strs[0])||"编号".equals(strs[0])){
                return i;
            }
        }
        return -1;
    }

    /**
     * 获取集合中最后一个对象
     * @param originIndexDatas
     * @return
     */
    private  OriginIndexData getLastOriginIndexData(List<OriginIndexData> originIndexDatas){
        return NullCheckUtils.isNull(originIndexDatas)?null:originIndexDatas.get(originIndexDatas.size()-1);
    }

    /**
     * 合并值与单位
     * @param val
     * @param unit
     * @return
     */
    private String concatValAndUnit(String val,String unit){
        if(NullCheckUtils.isNull(unit)){
            return val;
        }

        return String.format("%s(%s)",val,unit);
    }


    /**
     * 为字符串拆分单位
     * @param val
     * @return
     */
    private  String[] splitUnit(String val){
        String leftBracket="(";
        String rightBracket=")";

        String[] result=new String[2];
        boolean flag=val.contains(leftBracket)&&val.contains(rightBracket);
        if(flag){
            int leftIndex=val.indexOf(leftBracket);
            int rightIndex=val.lastIndexOf(rightBracket);
            String str1=val.substring(0,leftIndex);
            String str2=val.substring(leftIndex+1,rightIndex);
            result[0]=str1;
            result[1]=str2;
        }else{
            result[0]=val;
            result[1]=null;
        }
        return result;
    }

    /**
     * 列坐标实体
     */
    @AllArgsConstructor
    @Data
    private static class RowIndexModel{
        private String rowIndex;
        private boolean isMatch;

    }
}
